package java5.genericity.standard;

import java.util.*;
import java.util.function.Function;

public class Method {


    public void demo() {
        /**
         * 恒等  类似强制转型
         */
        String a = Function.<String>identity().apply(String.valueOf(1));
        //泛型单利工厂
        List<String> strings = Collections.<String>emptyList();
        //Collections.reverseOrder()
    }


    /**
     * 利用通配符
     * <p>
     * 助记符  PECS 表示
     * producer-extends  consumer-super
     */
    public void demo2() {
        java5.genericity.standard.Stack<Number> numberStack = new Stack<>();
        Iterator<Integer> iterator = new ArrayList<Integer>().iterator();
        //出错
        //numberStack.pushAll(iterator);
        numberStack.pushAllExtends(iterator);

        List<Object> det = new ArrayList<>();
        //出错
        //numberStack.pollAll(det);
        numberStack.pollAllSuper(det);

        //Set<Integer> integers = Set.of(1, 2, 3);
        //Set<Double> doubles = Set.of(1.0, 2.0);

        //Set<? extends Number> numbers = unionGeneral(integers, doubles);
        //Set<Number> numbers = unionGeneral(integers, doubles);
    }

    /**
     * 泛型方法
     *
     * @param a
     * @param b
     * @param <E>
     * @return
     */
    public static <E> Set<E> union(Set<E> a, Set<E> b) {
        Set<E> ret = new HashSet<>(a);
        ret.addAll(b);
        return ret;
    }


    /**
     * 通配符泛型方法
     *
     * @param a
     * @param b
     * @param <E>
     * @return 返回值不能用统配符 Set<? extends E> 如果使用那么接受值的地方 也强制使用统配符了
     */
    public static <E> Set<E> unionGeneral(Set<? extends E> a, Set<? extends E> b) {
        Set<E> ret = new HashSet<>(a);
        ret.addAll(b);
        return ret;
    }


    public static <E extends Comparable<E>> E max(Collection<E> c) {
        Collection<E> es = Objects.requireNonNull(c);
        E ret = null;
        for (E e : es) {
            if (e == null || e.compareTo(ret) > 0) {
                ret = Objects.requireNonNull(e);
            }
        }
        return ret;
    }


    public static <E> E swapHelper(List<E> list, int i, int j) {
        return list.set(i, list.set(j, list.get(i)));
    }

    public static void swap(List<?> list, int i, int j) {
        swapHelper(list, i, j);
    }

}
